import { RedisService } from '@common/reids/redis.service';
import { RoomService } from '../room/room.service';
import * as axios from 'axios';
import { defaultConfig } from '@game/config/config';
import { Injectable } from '@nestjs/common';
import { wsGlobal } from '@game/config/config';
import { respData } from './message.utils';

@Injectable()
export class SocketService {
  constructor(
    public readonly roomService: RoomService,
    public readonly redisService: RedisService,
  ) {}

  /**
 * 
没有了内置的缓存room  需要自己整一个全局对象去保存 直接reids保存
 key  room_roomId   [{user}]  用户信息将被长久关联 结合内存里的socket 判断在线与否
 即使服务器关闭，reids更换，数据库也有一份关系表
 一开始reids的数据肯定是来源数据库，然后socket进行更新操作，和客户端逻辑一样 

 */
  notifyGroup = async (action, data, otherAction = 'joinGroup') => {
    wsGlobal.$socketChat[data.userId] &&
      wsGlobal.$socketChat[data.userId].socket.emit(action, data);

    const res: any = await this.roomService.joinRoom(data);
    if (res) {
      //广播不行了 自己来
      res.map((user) => {
        if (user.userId !== data.userId) {
          wsGlobal.$socketChat[user.userId] &&
            wsGlobal.$socketChat[user.userId].socket.emit(otherAction, data);
        }
      });
    }
    if (data.id) {
      delete data.id;
      this.emit(action, data);
    }
  };
  notifyMessage = (action, data) => {
    // 来找人
    console.log(action)
    wsGlobal.$socketChat[data.userId] &&
      wsGlobal.$socketChat[data.userId].socket.emit(action, data);

    if (data.id) {
      delete data.id;
      this.emit(action, data);
    }
  };
  systemNotify = (action, data) => {
    for (const key in wsGlobal.$socketChat) {
      console.log(key);
      console.log(wsGlobal.$socketChat[key]);

      if (wsGlobal.$socketChat[key] && wsGlobal.$socketChat[key].socket) {
        wsGlobal.$socketChat[key].socket.emit(action, data);
      }
    }
  };
  notifyMessageGroup = async (action, data,specailBack=(user:any)=>{}) => {
    // 来找人
    // 其他服务有这个房间 需要拦截一下
    const res: any = await this.roomService.getUsersInRoom(data);
    if (res) {
      //广播不行了 自己来
      res.map((user, index) => {

        if (wsGlobal.$socketChat[user.userId]) {

          // console.log(
          //   action,
          //   respData[data.type],
          //   '发送',
          //   index + 1,
          //   wsGlobal.$socketChat[user.userId].userId,
          // );
          var rs = data;
          //如果不需要发给发送方，则跳过
          if(rs.userId == user.userId && (data.includSender !=undefined && data.includSender != true)){
          }else{
            data.userId=user.userId
           wsGlobal.$socketChat[user.userId].socket.emit(action, data);
          }
        }else{
          specailBack && specailBack(user)
        }
    
      });
    }
    if (data.id) {
      delete data.id;
      this.emit(action, data);
    }
  };

  /**
   * 必须把socketio 群组相关的自己写  小程序兼容不了貌似是阉割了ping保活 room推送不了  单个socket消息没问题 orz~~~
   * @param {*} action
   * @param {*} data
   */
  exitGroup = async (data) => {
    const res: any = await this.roomService.leave(data);
    if (res) {
      wsGlobal.$socketChat[data.userId] &&
        wsGlobal.$socketChat[data.userId].socket.emit('exitGroup', data);
      //广播不行了 自己来
      res.map((user) => {
        if (user.userId !== data.userId) {
          wsGlobal.$socketChat[user.userId] &&
            wsGlobal.$socketChat[user.userId].socket.emit('exitGroup', data);
        }
      });
    }

    if (data.id) {
      delete data.id;
      this.emit('exitGroup', data);
    }
  };

  destoryRoom = async (data) => {
    console.log(data.roomId, '解散了');
    data.message = '解散了';
    const res: any = await this.roomService.getUsersInRoom(data);
    if (res) {
      res.map(async (user) => {
        if (wsGlobal.$socketChat[user.userId]) {
          await this.roomService.leave(data);
          wsGlobal.$socketChat[user.userId].socket.emit('destoryRoom', data);
        }
      });
    }

    if (data.id) {
      delete data.id;
      this.emit('destoryRoom', data);
    }
  };

  /**
   * 由转发而来，遍历该服务器上的房间去寻找通知对象
   */
  transform = async (action, data) => {
    const usersList: any = await this.redisService.hget(
      'members_' + data.roomId,
    );

    if (usersList) {
      //广播不行了 自己来
      usersList.map((user) => {
        wsGlobal.$socketChat[user.userId] &&
          wsGlobal.$socketChat[user.userId].socket.emit(action, data);
      });
    }

    //更新当前这个房间用户状态
    const res = await this.roomService.roomUsersMapData({
      users: usersList,
      roomId: data.roomId,
      userId: data.userId,
      status: 0,
    });
    console.log('room_close', data.roomId, res);
  };

  emit = (action, data) => {
    return this.crossSync(action, data);
  };

  async crossSync(action, params) {
    // const ips = (await this.redisService.hkeys('-socket-chat')).filter(
    //   (ip) => ip !== wsGlobal.host && ip !== wsGlobal.host_ip,
    // );
    // const ips = defaultConfig.redisIps;

    // // 转发要排除自己的服务哦  不然会收到多条消息
    // if (!ips) {
    //   // console.log("没有发现服务！！！");
    //   return;
    // }

    // console.log(ips);
    // const blackList = await this.redisService.blackList();
    // ips.forEach(async (ip) => {
    //   //拦截黑名单
    //   if (blackList.includes(ip)) {
    //     console.log('拉黑ip：', ip);
    //     return;
    //   }
    //   try {
    //     await axios.default.post(
    //       `http://${ip}:${defaultConfig.port}/api/websocket/sync`,
    //       {
    //         action,
    //         data: JSON.stringify(params),
    //       },
    //       { timeout: 1000 },
    //     );
    //   } catch (error) {
    //     console.log(error);
    //     this.redisService.addBlackList(ip);
    //   }
    // });
    return 'ok';
    // 测试服务器见转发
    // request({
    //   method: "POST",
    //   uri: `http://127.0.0.1:3008/api/websocket/sync`,
    //   form: {
    //     action,
    //     data: JSON.stringify(params),
    //   },
    //   json: true,
    // });
  }
  async crossSync2(action, params) {
    // const ips = await this.redisService.hkeys('-socket-chat');
    const ips = defaultConfig.redisIps;
    if (!ips) {
      // console.log("没有发现服务！！！");
      return;
    }

    console.log(ips);
    const blackList = [];
    // const blackList = await this.redisService.blackList();
    ips.forEach(async (ip) => {
      //拦截黑名单
      if (blackList.includes(ip)) {
        console.log('拉黑ip：', ip);
        return;
      }
      try {
        await axios.default.post(
          `http://${ip}:${defaultConfig.port}/api/websocket/sync`,
          {
            action,
            data: JSON.stringify(params),
          },
          { timeout: 1000 },
        );
      } catch (error) {
        // console.log(error);
        // this.redisService.addBlackList(ip);
      }
    });
    return 'ok';
  }
}
